#include "house.h"
#include "monitor.h"
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

void iniciaCasa(DadosPersonagem dados[])
{
	strcpy(dados[0].nome, "Sheldon");
	dados[0].numero = 0;
	strcpy(dados[1].nome, "Amy");
	dados[1].numero = 1;
	strcpy(dados[2].nome, "Leonard");
	dados[2].numero = 2;
	strcpy(dados[3].nome, "Penny");
	dados[3].numero = 3;
	strcpy(dados[4].nome, "Howard");
	dados[4].numero = 4;
	strcpy(dados[5].nome, "Bernardette");
	dados[5].numero = 5;
}

void iniciaProblema()
{
	int i;
	pthread_t t_personagem[NUM_MAX_REQUERENTES_FORNO]; //thread personagens
	pthread_t t_mediador; //thread mediador - Raj;
	Monitor monitor;
	Personagem numt_personagem[NUM_MAX_REQUERENTES_FORNO]; //Array de personagens
	Personagem mediador; // Mediador - Raj
	pthread_attr_t attr;
	pthread_attr_init(&attr);
	pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
	iniciaMonitor(&monitor);
	iniciaMediador(&monitor, &mediador);
	iniciaValoresPersonagens(numt_personagem, &monitor);
	pthread_create(&t_mediador, &attr, (void *)threadMediador, (void *) &mediador);
	//Cria Threads dos personagens
	for (i = 0; i < NUM_MAX_REQUERENTES_FORNO; i++)
	{
		esperaRandomica();
		pthread_create(&t_personagem[i], &attr, (void *)threadPersonagem, (void *) &numt_personagem[i]);
	}
	//Aguarda thread do mediador
	pthread_join(t_mediador, NULL);
	//Aguarda thread dos personagens
	for (i = 0; i < NUM_MAX_REQUERENTES_FORNO; i++) pthread_join(t_personagem[i], NULL);
}

void iniciaValoresPersonagens(Personagem *personagens, Monitor *m)
{
	int i;
	for (i = 0; i < NUM_MAX_REQUERENTES_FORNO; i++)
	{
		personagens[i].m = m;
		personagens[i].num_cliente = i;
		personagens[i].quantidadeUsoForno = 0;
	}
}

//Raj
void iniciaMediador(Monitor *m, Personagem *mediador)
{
	mediador->m = m;
	mediador->num_cliente = 6;
}

void iniciaFila()
{
	int i;
	for(i = 0; i < 1000; i++)
	{
		fila[i].numero = -1;
		fila[i].quantidadeDeUso = -1;
	}
}

void adicionaFila(int numero, int quantidade)
{
	//Se não existe na fila, adiciona
	if(!verificaSeExisteNaFila(numero))
	{
		int i;
		for(i = 0; i < 1000; i++)
		{
			if(fila[i].numero == -1)
			{
				fila[i].numero = numero;
				fila[i].quantidadeDeUso = quantidade;
				break;
			}
		}
	}
}
void removeFila(int numero)
{
	int i, j, condicao = 1;
	for(i = 0, j = 0; i < 1000; i++, j++)
	{
		if(fila[i].numero == numero && condicao)
		{
			i++;
			condicao = 0;
		}
		fila[j] = fila[i];
	}

	//trata ultima posição da fila
	if(j != i)
	{
		fila[j].numero = -1;
		fila[j].quantidadeDeUso = -1;
	}
}

int removePrimeiroDaFila()
{
	int numero = fila[0].numero; //primeira posição
	removeFila(numero);
	return numero;
}

int verificaSeExisteNaFila(int numero)
{
	int i;
	for(i = 0; i < 1000; i++)
	{
		if(fila[i].numero == numero)
		{
			return 1;
		}
	}
	return 0;
}

char *qualPersonagem(int numero)
{
	int i;
	for(i = 0; i < NUM_MAX_REQUERENTES_FORNO; i++)
	{
		if(dados[i].numero == numero)
		{
			return dados[i].nome;
		}
	}
	return "";
}

int tamanhoDaFila()
{
	int contador = 0;
	while(fila[contador].numero != -1)
	{
		contador++;
	}
	return contador;
}

void realocaNamorados(int Amy, int Bernardette, int Penny)
{
	if(Amy) colocaAmyNaFrenteSheldon();
	if(Bernardette) colocaBernadetteyNaFrenteHoward();
	if(Penny) colocaPennyNaFrenteLeonard();
}

int qualPersonagemEstaNaFrente(int personagem1, int personagem2)
{
	if(verificaSeExisteNaFila(personagem1) && verificaSeExisteNaFila(personagem2))
	{
		int tamanho = tamanhoDaFila();
		int i;
		for(i = 0; i < tamanho; i++)
		{
			if(fila[i].numero == personagem1) return 0;
			else if(fila[i].numero == personagem2) return 1;
		}
	}
	return 0;
}

void colocaAmyNaFrenteSheldon()
{
	if(verificaSeExisteNaFila(0) && verificaSeExisteNaFila(1))
	{
		int i;
		int tamanho = tamanhoDaFila();
		for(i = 0; i < tamanho; i++)
		{
			if(fila[i].numero == 0) fila[i].numero = 1;
			i++;
			if(fila[i].numero == 1) fila[i].numero = 0;
		}
	}
}
void colocaBernadetteyNaFrenteHoward()
{
	if(verificaSeExisteNaFila(4) && verificaSeExisteNaFila(5))
	{
		int i;
		int tamanho = tamanhoDaFila();
		for(i = 0; i < tamanho; i++)
		{
			if(fila[i].numero == 4) fila[i].numero = 5;
			i++;
			if(fila[i].numero == 5) fila[i].numero = 4;
		}
	}
}

void colocaPennyNaFrenteLeonard()
{
	if(verificaSeExisteNaFila(2) && verificaSeExisteNaFila(3))
	{
		int i;
		int tamanho = tamanhoDaFila();
		for(i = 0; i < tamanho; i++)
		{
			if(fila[i].numero == 2) fila[i].numero = 3;
			i++;
			if(fila[i].numero == 3) fila[i].numero = 2;
		}
	}
}

